import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'
import { Reflector } from '@nestjs/core'
import { JwtService } from '@nestjs/jwt'
import { HEAD_TOKEN, USER_TOKEN_DATA } from '../constants/config.contants'
import { AUTHORIZE_KEY_METADATA } from '../constants/decorator.contants'
import { JwtExistException, JwtInvalidException } from '../exception/JwtException'


@Injectable()
export class JwtAuthGuard implements CanActivate {
  constructor(private reflector: Reflector, private jwtService: JwtService) { }

  async canActivate(context: ExecutionContext): Promise<boolean> {

    const authorize = this.reflector.get<boolean>(AUTHORIZE_KEY_METADATA, context.getHandler())

    if (authorize) {
      return true
    }

    const request = context.switchToHttp().getRequest()
    const token = request.headers[HEAD_TOKEN] as string

    if (token) {
      try {
        request[USER_TOKEN_DATA] = this.jwtService.verify(token)
        return true
      } catch (error) {
        throw new JwtInvalidException()
      }
    } else {
      throw new JwtExistException()
    }
  }

}
